package com.youbug.system.service.impl;

import cn.hutool.crypto.symmetric.AES;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youbug.common.constant.DicTypeContent;
import com.youbug.system.entity.Dictionary;
import com.youbug.system.entity.User;
import com.youbug.common.exception.PasswordException;
import com.youbug.system.mapper.UserMapper;
import com.youbug.system.service.IDictionaryService;
import com.youbug.system.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.system.vo.PwdVo;
import com.youbug.system.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author sunwx
 * @since 2022-12-05
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private AES aes;
    @Autowired
    private IDictionaryService dictionaryService;

    @Override
    public IPage<User> getUserPage(UserVo userVo) {

        Page<User> userPage = new Page<>();

        userPage.setCurrent(userVo.getCurrentPage());

        userPage.setSize(userVo.getPageSize());

        QueryWrapper<User> wrapper = new QueryWrapper<>();

        if(StringUtils.hasText(userVo.getUsername())){

            wrapper.eq("username", userVo.getUsername());
        }

        if(StringUtils.hasText(userVo.getGender())){

            wrapper.eq("gender", userVo.getGender());
        }

        Page<User> page = this.page(userPage, wrapper);

        return page;
    }

    @Override
    public boolean updatePassword(PwdVo pwdVo) {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if(pwdVo.getNewPassword().equals(pwdVo.getOldPassword())){
            throw new PasswordException("新密码不能与旧密码相同");
        }
        if(!pwdVo.getNewPassword().equals(pwdVo.getReNewPassword())){
            throw new PasswordException("两次输入新密码不一致");
        }
        wrapper.select("password");
        wrapper.eq("id", pwdVo.getUserId());
        wrapper.eq("password", aes.encryptBase64(pwdVo.getOldPassword()));
        User user = this.getOne(wrapper);
        if(user == null){
            throw new PasswordException("旧密码输入错误");
        }

        User newUser = new User();
        newUser.setPassword(aes.encryptBase64(pwdVo.getNewPassword()));
        return  this.update(newUser, wrapper);
    }

    @Override
    public boolean importUsers(MultipartFile file) {

        IUserService userService = this;

        Dictionary localSource = dictionaryService.getOneByTypeAndCode(DicTypeContent.SYS_CONFIG, "importExcel");

        String rootFilePath = localSource.getValue() + "user/";

        File newFile = new File(rootFilePath);

        try {
            if(!newFile.exists()){
                boolean b = newFile.mkdirs();
            }
            file.transferTo(newFile);

        } catch (IOException e) {
            e.printStackTrace();
        }

        EasyExcel.read(newFile, User.class, new ReadListener<User>() {
            IUserService userServiceTemp = userService;
            /**
             * 单次缓存的数据量
             */
            public static final int BATCH_COUNT = 100;
            /**
             *临时存储
             */
            private List<User> cachedDataList = new ArrayList<>(BATCH_COUNT);

            @Override
            public void invoke(User data, AnalysisContext context) {
                cachedDataList.add(data);
                if (cachedDataList.size() >= BATCH_COUNT) {
                    saveData();
                    // 存储完成清理 list
                    cachedDataList =  new ArrayList<>(BATCH_COUNT);
                }
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                saveData();
            }
            /**
             * 加上存储数据库
             */
            private void saveData() {
                cachedDataList.forEach(e -> e.setPassword("mt/oiC+mLbN96sUB1DUdpA=="));// 密码默认111111
                userServiceTemp.saveBatch(cachedDataList);
            }
        }).sheet().doRead();

        return true;
    }
}
